package com.ruoyi.web.bankCard;


import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.web.utils.CommonUtil;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@Slf4j
@RequestMapping("/bankCard")
public class BankCardController {


    @Value("${wxpay.appid}")
    private String appId;
    @Value("${wxpay.appSecret}")
    private String appSecret;
    @Value("${wxpay.mchSerialNo}")
    private String mchSerialNo;

    @Value("${wxpay.keyPath}")
    private String keyPath;
    @Value("${wxpay.domain}")
    private String domain;
    @Value("${wxpay.certP12Path}")
    private String certP12Path;
    @Value("${wxpay.certPath}")
    private String certPath;
    @Value("${wxpay.mchId}")
    private String mchId;


    /**
     * 发放中信银行立减金
     */
    @PostMapping("/sendCard")
    public AjaxResult sendCard() throws Exception{

        CloseableHttpClient httpClient = getWechatPayHttpClientBuilder2().build();
        String sendCouponUrl = String.format("https://api.mch.weixin.qq.com/v3/marketing/favor/users/%s/coupons", "o1Vlqty90C5aeWSxe45MZi1uAOqQ");
        HashMap<String, String> paraMap = new HashMap<>();
        paraMap.put("stock_id", "20035748");
        paraMap.put("out_request_no", generateOrderNo(mchId));
        paraMap.put("appid", appId);
        paraMap.put("stock_creator_mchid", mchId);
        log.info("request url=" + sendCouponUrl);
        log.info("request params=" + JSONObject.toJSONString(paraMap));

        HttpPost httpPost = new HttpPost(sendCouponUrl);
        StringEntity reqEntity = new StringEntity(JSONObject.toJSONString(paraMap),
                ContentType.create("application/json", "utf-8"));
        httpPost.setEntity(reqEntity);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-Type", "application/json");

        CloseableHttpResponse response = null;
        try {
            log.info("微信发券接口地址："+sendCouponUrl+",入参："+JSONObject.toJSONString(httpPost));
            response = httpClient.execute(httpPost);
            log.info("微信发券接口返回结果code："+response.getStatusLine().getStatusCode()+",内容："+ EntityUtils.toString(response.getEntity()));
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(response.getEntity());
                log.info("response=" + result);
                return AjaxResult.success(result);
            } else {
                String result = EntityUtils.toString(response.getEntity());
                log.error("status_code=" + response.getStatusLine().getStatusCode() + ", response=" + result);
                return AjaxResult.error(result);
            }
        } catch (Exception e) {
            log.error("excepiton:" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;


    }







//    /**
//     * 查询信用卡卡卷信息
//     */
//    @PostMapping("/cardList")
//    public AjaxResult cardList(@RequestBody BankCardReq req) throws Exception{
//
//        CloseableHttpClient httpClient = getWechatPayHttpClientBuilder2().build();
//        String sendCouponUrl = String.format("https://api.mch.weixin.qq.com/v3/marketing/favor/stocks?offset=%d&limit=%d&stock_creator_mchid=%s&create_start_time=%s&create_end_time=%s",
//                req.getOffset(),req.getLimit(),wxPayV3Bean.getMchId(),toRFC3339(req.getCreate_start_time()),toRFC3339(req.getCreate_end_time()));
//        HttpGet httpGet = new HttpGet(sendCouponUrl);
//        httpGet.addHeader("Accept", "application/json");
//        httpGet.addHeader("Content-Type", "application/json");
//
//        CloseableHttpResponse response = null;
//        try {
//            log.info("微信发券接口地址："+sendCouponUrl+",入参："+JSONObject.toJSONString(httpGet));
//            response = httpClient.execute(httpGet);
//            log.info("微信发券接口返回结果code："+response.getStatusLine().getStatusCode()+",内容："+ EntityUtils.toString(response.getEntity()));
//            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//                String result = EntityUtils.toString(response.getEntity());
//                // 创建 ObjectMapper 实例
//                ObjectMapper objectMapper = new ObjectMapper();
//
//                // 将 JSON 字符串转换为 CouponResponse 对象
//                CouponResponse couponResponse = objectMapper.readValue(result, CouponResponse.class);
//
//                log.info("response=" + couponResponse);
//                return AjaxResult.success(couponResponse);
//            } else {
//                String result = EntityUtils.toString(response.getEntity());
//                log.error("status_code=" + response.getStatusLine().getStatusCode() + ", response=" + result);
//                return AjaxResult.error(result);
//            }
//        } catch (Exception e) {
//            log.error("excepiton:" + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (response != null) {
//                try {
//                    response.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//
//        return null;
//
//    }

//
//    /**
//     * 创建中信银行卡卷 暂时不支持api发卷
//     */
//    @PostMapping("/createCard")
//    public AjaxResult createCard() throws Exception{
//
//        CloseableHttpClient httpClient = getWechatPayHttpClientBuilder2().build();
//        String sendCouponUrl = "https://api.mch.weixin.qq.com/v3/marketing/favor/coupon-stocks";
//        HashMap<String, String> paraMap = new HashMap<>();
//        paraMap.put("stock_name", "微信支付代金券批次");
//        paraMap.put("belong_merchant", wxPayV3Bean.getMchId());
//        //可用开始时间
//        paraMap.put("available_begin_time", toRFC3339(new Date()));
//        //可用结束时间
//        paraMap.put("available_end_time",toRFC3339(DateUtil.endOfMonth(new Date())));
//
//        //发放规则
//        HashMap<String, Object> rule = new HashMap<>();
//        //创建卷数量
//        rule.put("max_coupons",10);
//        //总预算
//        rule.put("max_amount",20);
//        //单个用户可领取数量
//        rule.put("max_coupons_per_user",1);
//        //多个微信号身份证属于一个人的时候限领
//        rule.put("natural_person_limit",true);
//        //若开启防刷拦截，当用户命中恶意、小号、机器、羊毛党、黑产等风险行为时，无法成功发放代金券。
//        rule.put("prevent_api_abuse",true);
//        paraMap.put("stock_use_rule",JSONObject.toJSONString(rule));
//        //样式设置
//        //发放规则
//        HashMap<String, Object> style = new HashMap<>();
//        style.put("description","微信支付营销代金券");
//
//        //核销规则
//        HashMap<String,Object> hxrule = new HashMap<>();
//
//
//
//
//
//
//        HttpPost httpPost = new HttpPost(sendCouponUrl);
//        StringEntity reqEntity = new StringEntity(JSONObject.toJSONString(paraMap),
//                ContentType.create("application/json", "utf-8"));
//        httpPost.setEntity(reqEntity);
//        httpPost.addHeader("Accept", "application/json");
//        httpPost.addHeader("Content-Type", "application/json");
//
//        CloseableHttpResponse response = null;
//        try {
//            log.info("微信发券接口地址："+sendCouponUrl+",入参："+JSONObject.toJSONString(httpPost));
//            response = httpClient.execute(httpPost);
//            log.info("微信发券接口返回结果code："+response.getStatusLine().getStatusCode()+",内容："+ EntityUtils.toString(response.getEntity()));
//            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//                String result = EntityUtils.toString(response.getEntity());
//                log.info("response=" + result);
//                return AjaxResult.success(result);
//            } else {
//                String result = EntityUtils.toString(response.getEntity());
//                log.error("status_code=" + response.getStatusLine().getStatusCode() + ", response=" + result);
//                return AjaxResult.error(result);
//            }
//        } catch (Exception e) {
//            log.error("excepiton:" + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (response != null) {
//                try {
//                    response.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//
//        return null;
//
//
//    }










    /**
     * 将指定的时间转换为 RFC3339 格式
     *
     * @param date 需要转换的时间对象
     * @return 转换后的 RFC3339 格式字符串
     */
    public static String toRFC3339(Date date) {
        if (date == null) {
            throw new IllegalArgumentException("Date cannot be null");
        }

        // 设置 RFC3339 格式
        SimpleDateFormat rfc3339Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
        rfc3339Format.setTimeZone(TimeZone.getTimeZone("UTC")); // 设置时区为 UTC

        return rfc3339Format.format(date);
    }



    private WechatPayHttpClientBuilder getWechatPayHttpClientBuilder2() throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                new FileInputStream(keyPath));

        // 获取证书管理器实例
        // 初始化 CertificatesManager
        CertificatesManager certificatesManager = CertificatesManager.getInstance();

        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(mchId);
        // 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        X509Certificate certificate = verifier.getValidCertificate();
        List<X509Certificate> certificates = new ArrayList<>();
        certificates.add(certificate);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, CommonUtil.getSerialNumber(mchSerialNo,certPath), merchantPrivateKey)
                .withWechatPay(certificates);
        // ... 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签
        return builder;
    }

    /**
     * 生成商户单据号
     *
     * @param merchantId 商户ID
     * @return 商户单据号
     */
    public static String generateOrderNo(String merchantId) {
        // 获取当前日期，格式为 yyyyMMdd
        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());

        // 生成唯一流水号，使用UUID的一部分
        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8);

        // 拼接商户单据号，格式为：商户ID + 日期 + 流水号
        return merchantId + "|" + date + "|" + uuidPart;
    }


}
